#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "../include/HashTable.h"

extern HashTableNode *hashtable[26][26];

int constructHash(NAryNode *temp)
{
	if(temp!=NULL)
	{
		insert_hash_item(temp->fd.fileName, temp);
		constructHash(temp->next);
		constructHash(temp->files);
		constructHash(temp->directories);
	}
	return 1;
}

int construct_hash_table()
{
	
	initialize_hash_table();
	NAryNode *temp = nAryRoot;
	constructHash(temp->files);
	constructHash(temp->directories);
	return 1;
}

int initialize_hash_table()
{
	int i, j;
	for(i=0; i<26; i++)
		for(j=0; j<26; j++)
			hashtable[i][j] = NULL;
	return 1;
}
int insert_hash_item(char *fileName, NAryNode *nAryNode)
{
	int row, col;
	char *file = (char*)malloc((strlen(fileName)+1)*sizeof(char));
	HashTableNode *temp = (HashTableNode*)malloc(sizeof(HashTableNode));
	temp->nAryNode = nAryNode;
	temp->next = NULL;
	temp->prev = NULL;
	strcpy(file, fileName);
	temp->fileName = file;
	row = 0;
	col = 0;
	if( isalpha(fileName[0]) )
		row = (tolower(fileName[0])-'a')%26;
	if( isalpha(fileName[1]) )
		col = (tolower(fileName[1])-'a')%26;
	HashTableNode *temp2 = hashtable[row][col];
	if(temp2==NULL)
	{
		hashtable[row][col]=temp;
		return 1;
	}
	temp->next = hashtable[row][col];
	hashtable[row][col] = temp;
	return 1;	
}

/*
int insert_hash_item(char *fileName, NAryNode *nAryNode)
{
	int row, col;
	char *file = (char*)malloc((strlen(fileName)+1)*sizeof(char));
	HashTableNode *temp = (HashTableNode*)malloc(sizeof(HashTableNode));
	temp->nAryNode = nAryNode;
	temp->next = NULL;
	temp->prev = NULL;
	strcpy(file, fileName);
	temp->fileName = file;
	row = 0;
	col = 0;
	if( isalpha(fileName[0]) )
		row = (tolower(fileName[0])-'a')%26;
	if( isalpha(fileName[1]) )
		col = (tolower(fileName[1])-'a')%26;
	HashTableNode *temp2 = hashtable[row][col];
	if(temp2==NULL)
	{
		hashtable[row][col]=temp;
		return 1;
	}
	while(temp2->next != NULL && strcmp(temp2->fileName, temp->fileName)<0)
		temp2 = temp2->next;
	if(temp2->next!=NULL)
	{
		temp->prev = temp2->prev;
		temp->next = temp2;
		if(temp->prev != NULL)
			temp->prev->next = temp;
		else
			hashtable[row][col]=temp;
		temp->next->prev = temp;
	}
	else
	{
		if(strcmp(temp2->fileName, temp->fileName)<0)
		{
			temp->next = NULL;//temp2->next
			temp->prev = temp2;			
			temp->prev->next = temp;
		}
		else
		{
			temp->next = temp2;
			temp->prev = temp2->prev;
			if(temp->prev!=NULL)		//Start of the Hash chain
				temp->prev->next = temp;
			else
				hashtable[row][col]=temp;
			temp->next->prev = temp;
		}
	}
	return 1;	
}
*/
/*
HashTableNode* search_hash_item(char *fileName)
{
	int row, col;
	HashTableNode* temp;
	row = 0;
	col = 0;
	if( isalpha(fileName[0]) )
		row = (tolower(fileName[0])-'a')%26;
	if( isalpha(fileName[1]) )
		col = (tolower(fileName[1])-'a')%26;
	temp = hashtable[row][col];
	while(temp!=NULL)
	{
		if(strncmp(temp->fileName, fileName, strlen(fileName))==0) 
			break;
		temp=temp->next;
	}
	return temp;
}
*/
HashTableNode* search_hash_item(char *fileName)
{
	int row, col;
	HashTableNode* temp;
	row = 0;
	col = 0;
	if( isalpha(fileName[0]) )
		row = (tolower(fileName[0])-'a')%26;
	if( isalpha(fileName[1]) )
		col = (tolower(fileName[1])-'a')%26;
	temp = hashtable[row][col];
	return temp;
}

int delete_hash_item(NAryNode *nAryNode)
{
	HashTableNode *hashTableNode = search_hash_item(nAryNode->fd.fileName);
	hashTableNode->next->prev = hashTableNode->prev;
	hashTableNode->prev->next = hashTableNode->next;
	free(hashTableNode);
}

/*
int main()
{
	char input[100];
	initialize_hash_table();
	while(1)
	{	
		//Input	
		scanf("%s", input);
		if(strcmp(input, "exit")==0)
			break;
		else
			insert_hash_item(input, NULL);
	}
	printf("End of Input");
	while(1)
	{
		scanf("%s", input);
		if(strcmp(input, "exit")!=0)
		{
			HashTableNode *temp = search_hash_item(input);
			if(temp==NULL)
				printf("File Not Found");
			else
			{
				printf("File Found at location %u", temp);
			}
		}
		else
			break;
	}
	HashTableNode *node = hashtable[0][0];
	while(node!=NULL)
	{
		printf("%s", node->fileName);
		node = node->next;
	}
	return 0;
}
*/
